/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.report.statistics.targetResponsibility;

import com.koron.common.domain.KpiStatistics;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.generator.GetHardwareIdFailedException;
import com.koron.common.generator.InvalidSystemClockException;
import com.koron.common.service.KpiStatisticsService;
import com.koron.purpose.mapper.KPITemplateMapper;
import com.koron.report.bean.StatisticsBean;
import com.koron.report.management.StatisticsManagement;
import com.koron.report.mapper.statistics.SafetyMeetingStatisticsMapper;
import com.koron.report.statistics.Contants;
import com.koron.report.statistics.StatisticsService;
import com.koron.system.domain.District;
import com.koron.system.domain.DistrictCorpRelation;
import com.koron.system.mapper.DistrictMapper;
import com.koron.system.service.api.DistrictService;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 安全会议统计（特指法律法规规定的会议）
 */
@Service("safetyMeetingStatisticsService")
@SuppressWarnings("deprecation")
public class SafetyMeetingStatisticsServiceImpl implements InitializingBean, StatisticsService {

    // 指标code
    private final String KPICODE = "0005";

    private final Logger logger = LoggerFactory.getLogger(AnnualSafPlanCompRateServiceImpl.class);

    @Autowired
    private StatisticsManagement statisticsManagement;

    @Autowired
    private KpiStatisticsService kpiStatisticsService;

    // 获取片区信息service
    @Autowired
    private DistrictService districtService;

    @Override
    public void statisticsMonth(int year, int month) {
        SessionFactory factory = null;
        try {
            factory = new SessionFactory();
            SafetyMeetingStatisticsMapper mapper = factory.getMapper(SafetyMeetingStatisticsMapper.class);
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, month - 1, 1, 0, 0, 0);
            Date startDate = calendar.getTime();
            calendar.add(Calendar.MONTH, 1);
            Date stopDate = calendar.getTime();
            String kpiName = factory.getMapper(KPITemplateMapper.class).queryTemplateByCode(KPICODE).getName();
            // 统计查询: 按公司统计
            List<StatisticsBean> list = mapper.statistics(startDate, stopDate);
            String dateValue = year + "-" + month;
            if (month < 10) {
                dateValue = year + "-0" + month;
            }
            assemblyData(list, kpiName, Contants.DATE_TYPE_1, dateValue, Contants.STATISTICAL_TYPE_3);
            // 统计查询: 按片区统计
            districtTotal(factory, list, kpiName, Contants.DATE_TYPE_1, dateValue);
            // 统计查询: 按集团统计
            blocTotal(mapper.statisticsBloc(startDate, stopDate), kpiName, Contants.DATE_TYPE_1,
                    dateValue, Contants.STATISTICAL_TYPE_5);
        } catch (Exception e) {
            if (factory != null) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            logger.error(String.format("安全会议统计（特指法律法规规定的会议）按月(%o-%o)统计执行发生错误", year, month));
        }finally {
            if (factory != null) {
                factory.close();
            }
        }
    }

    @Override
    public void statisticsQuarter(int year, int quarter) {
        SessionFactory factory = null;
        try {
            factory = new SessionFactory();
            SafetyMeetingStatisticsMapper mapper = factory.getMapper(SafetyMeetingStatisticsMapper.class);
            Calendar calendar = Calendar.getInstance();
            int month = (quarter - 1) * 3 + 1;
            calendar.set(year, month - 1, 1, 0, 0, 0);
            Date startDate = calendar.getTime();
            calendar.add(Calendar.MONTH, 3);
            Date stopDate = calendar.getTime();
            String kpiName = factory.getMapper(KPITemplateMapper.class).queryTemplateByCode(KPICODE).getName();
            // 统计查询: 按公司统计
            List<StatisticsBean> list = mapper.statistics(startDate, stopDate);
            assemblyData(list, kpiName, Contants.DATE_TYPE_2, year + "-" + quarter, Contants.STATISTICAL_TYPE_3);
            // 统计查询: 按片区统计
            districtTotal(factory, list, kpiName, Contants.DATE_TYPE_2, year + "-" + quarter);
            // 统计查询: 按集团统计
            blocTotal(mapper.statisticsBloc(startDate, stopDate), kpiName, Contants.DATE_TYPE_2,
                    year + "-" + quarter, Contants.STATISTICAL_TYPE_5);
        } catch (Exception e) {
            if (factory != null) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            logger.error(String.format("安全会议统计（特指法律法规规定的会议）按季度(%o-%o季度)统计执行发生错误", year, quarter));
        }finally {
            if (factory != null) {
                factory.close();
            }
        }
    }

    @Override
    public void statisticsYear(int year) {
        SessionFactory factory = null;
        try {
            factory = new SessionFactory();
            SafetyMeetingStatisticsMapper mapper = factory.getMapper(SafetyMeetingStatisticsMapper.class);
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, 0, 1, 0, 0, 0);
            Date startDate = calendar.getTime();
            calendar.add(Calendar.YEAR, 1);
            Date stopDate = calendar.getTime();
            String kpiName = factory.getMapper(KPITemplateMapper.class).queryTemplateByCode(KPICODE).getName();
            // 统计查询: 按公司统计
            List<StatisticsBean> list = mapper.statistics(startDate, stopDate);
            assemblyData(list, kpiName, Contants.DATE_TYPE_3, String.valueOf(year), Contants.STATISTICAL_TYPE_3);
            // 统计查询: 按片区统计
            districtTotal(factory, list, kpiName, Contants.DATE_TYPE_3, String.valueOf(year));
            // 统计查询: 按集团统计
            blocTotal(mapper.statisticsBloc(startDate, stopDate), kpiName, Contants.DATE_TYPE_3,
                    String.valueOf(year), Contants.STATISTICAL_TYPE_5);
        } catch (Exception e) {
            if (factory != null) {
                factory.close(false);
            }
            logger.error("安全会议统计（特指法律法规规定的会议）按年(" + year + ")统计执行发生错误");
        }finally {
            if (factory != null) {
                factory.close();
            }
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Set<Object> handlers = statisticsManagement.getHandlers();
        handlers.add(this);
    }

    /**
     * 组装数据
     *
     * @param list            统计查询结果list
     * @param kpiName         指标name
     * @param dateType        日期类型 1月，2季，3年
     * @param dateValue       日期 月：2020-01，季2020-1/2/3/4,年2020
     * @param statisticalType 统计类型：1员工，2部门，3公司，4片区，5集团
     * @throws GetHardwareIdFailedException
     * @throws InvalidSystemClockException
     */
    private void assemblyData(List<StatisticsBean> list, String kpiName, Integer dateType, String dateValue,
                              Integer statisticalType) throws GetHardwareIdFailedException, InvalidSystemClockException {
        if (list != null && list.size() > 0) {
            List<KpiStatistics> insertList = new LinkedList<>();
            for (StatisticsBean statisticsBean : list) {
                KpiStatistics bean = new KpiStatistics(
                        DefaultIdGenerator.getInstance().generateLongId(),
                        kpiName,
                        KPICODE,
                        Float.valueOf(statisticsBean.getValue()),
                        dateType,
                        dateValue,
                        statisticalType,
                        statisticsBean.getCode(),
                        statisticsBean.getCodeName(),
                        new Date()
                );
                insertList.add(bean);
                kpiStatisticsService.delete(KPICODE, dateValue, statisticsBean.getCode());
            }
            kpiStatisticsService.batchInsert(insertList);
        }
    }

    /**
     * 根据code 获取value值
     *
     * @param list
     * @param code
     */
    private float getValueByCode(List<StatisticsBean> list, String code) {
        if (list != null && list.size() > 0) {
            for (StatisticsBean statisticsBean : list) {
                if (statisticsBean.getCode().equals(code)) {
                    return Float.valueOf(statisticsBean.getValue());
                }
            }
        }
        return 0f;
    }

    /**
     * 统计查询: 按片区统计
     *
     * @param factory
     * @param list
     * @param kpiName   指标name
     * @param dateType  日期类型 1月，2季，3年
     * @param dateValue 日期 月：2020-01，季2020-1/2/3/4,年2020
     */
    private void districtTotal(SessionFactory factory, List<StatisticsBean> list, String kpiName, Integer dateType, String dateValue)
            throws GetHardwareIdFailedException, InvalidSystemClockException {
        List<District> districtList = factory.getMapper(DistrictMapper.class).queryAllDistrict(null, null);
        if (districtList != null && districtList.size() > 0) {
            List<StatisticsBean> statisticsBeans = new LinkedList<>();
            for (District district : districtList) {
                // 根据片区code，获取片区下所有公司信息
                List<DistrictCorpRelation> districtCorpRelationList = districtService.queryAssociatedCorp(district.getCode());
                float value = 0f;
                if (districtCorpRelationList != null && districtCorpRelationList.size() > 0) {
                    for (DistrictCorpRelation districtCorpRelation : districtCorpRelationList) {
                        // 根据code 获取value值
                        value += getValueByCode(list, districtCorpRelation.getCorpCode());
                    }
                }
                statisticsBeans.add(new StatisticsBean(district.getCode(), district.getName(), Float.valueOf(value).toString()));
            }
            assemblyData(statisticsBeans, kpiName, dateType, dateValue, Contants.STATISTICAL_TYPE_4);
        }
    }

    /**
     * 统计查询: 按集团统计
     *
     * @param blocValue       集团统计值
     * @param kpiName         指标name
     * @param dateType        日期类型 1月，2季，3年
     * @param dateValue       日期 月：2020-01，季2020-1/2/3/4,年2020
     * @param statisticalType 统计类型：1员工，2部门，3公司，4片区，5集团
     * @throws GetHardwareIdFailedException
     * @throws InvalidSystemClockException
     */
    private void blocTotal(Integer blocValue, String kpiName, Integer dateType, String dateValue,
                           Integer statisticalType) throws GetHardwareIdFailedException, InvalidSystemClockException {
        kpiStatisticsService.insert(new KpiStatistics(
                DefaultIdGenerator.getInstance().generateLongId(),
                kpiName,
                KPICODE,
                Float.valueOf(blocValue),
                dateType,
                dateValue,
                statisticalType,
                Contants.BLOC_CODE,
                Contants.BLOC_NAME,
                new Date()
        ));
    }
}
